package com.ruige.account.oauth.controller;


import com.ruige.account.entity.Result;
import com.ruige.account.entity.StatusCode;
import com.ruige.account.entity.Uid;
import com.ruige.account.oauth.pojo.User;
import com.ruige.account.oauth.service.AuthService;
import com.ruige.account.oauth.util.AuthToken;
import com.ruige.account.oauth.util.CookieUtil;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;


@Controller
@RequestMapping("/oauth")
public class AuthController {

    @Autowired
    private AuthService authService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Value("${auth.clientId}")
    private String clientId;

    @Value("${auth.clientSecret}")
    private String clientSecret;

    @Value("${auth.cookieDomain}")
    private String cookieDomain = "";

    @Value("${auth.cookieMaxAge}")
    private int cookieMaxAge;


    @RequestMapping("/toLogin")
    public String toLogin(@RequestParam(value = "FROM", required = false, defaultValue = "") String from, Model model) {
        model.addAttribute("from", from);
        return "login";
    }

    @RequestMapping("/toRegister")
    public String toRegister() {
        return "register";
    }


    @RequestMapping("/login")
    @ResponseBody
    public Result login(@RequestBody User user, HttpServletRequest request) {
//        if (request.getRemoteHost() != null) {
//            cookieDomain = request.getRemoteHost();
//        }
//        System.out.println("cookieDomain = " + cookieDomain);

        if (StringUtils.isEmpty(user.getUsername())) {
            throw new RuntimeException("用户名不存在");
        }

        if (StringUtils.isEmpty(user.getPassword())) {
            throw new RuntimeException("密码不存在");
        }


        AuthToken authToken = authService.login(user.getUsername(), user.getPassword(), clientId, clientSecret);

        this.saveJtiToCookie(authToken.getJti(), authToken.getAccessToken(), authToken.getUserId(), authToken.getUsername());

        return new Result(true, StatusCode.OK, "登录成功", authToken.getJti());
    }


    @RequestMapping("/logout")
    @ResponseBody
    public Result logout(@RequestBody Uid uid) {
        System.out.println("uid = " + uid.getUid());
        if (uid != null) {
            Boolean flag = stringRedisTemplate.delete(uid.getUid());
            System.out.println("flag = " + flag);
            if (flag != null && flag) {
                return new Result(true, StatusCode.OK, "注销成功");
            } else {
                return new Result(false, StatusCode.ERROR, "注销失败");
            }
        } else {
            return new Result(false, StatusCode.ERROR, "注销失败");
        }

    }

    @RequestMapping("/register")
    @ResponseBody
    public Result register(@RequestBody User user, HttpServletRequest request) {

        if (StringUtils.isEmpty(user.getUsername())) {
            throw new RuntimeException("用户名不存在");
        }

        Boolean flag = authService.findByUsername(user.getUsername());
        if (!flag) {
            return new Result(false, StatusCode.ERROR, "用户已存在!");
        }

        if (StringUtils.isEmpty(user.getPassword())) {
            throw new RuntimeException("密码不存在");
        }

        if (StringUtils.isEmpty(user.getPhone().toString())) {
            throw new RuntimeException("手机号不存在");
        }

        String salt = BCrypt.gensalt();
        String hashpw = BCrypt.hashpw(user.getPassword(), salt);
        String password = user.getPassword();
        user.setPassword(hashpw);
        user.setCreatedTime(LocalDateTime.now());
        int insert = authService.register(user);
        user.setPassword(password);
        this.login(user, request);
        return new Result(true, StatusCode.OK, "注册成功");
    }

    //添加cookie的方法
    private void saveJtiToCookie(String jti, String accessToken, Integer userId, String username) {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        CookieUtil.addCookie(response, cookieDomain, "/", "uid", jti, cookieMaxAge, false);
        CookieUtil.addCookie(response, cookieDomain, "/", "Authorization", accessToken, cookieMaxAge, false);
        CookieUtil.addCookie(response, cookieDomain, "/", "userId", userId.toString(), cookieMaxAge, false);
        CookieUtil.addCookie(response, cookieDomain, "/", "username", username, cookieMaxAge, false);
//        CookieUtil.addCookie(response, "192.168.0.102", "/", "uid", jti, cookieMaxAge, false);
    }
}